package com.teemo.equipment.biz.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.teemo.equipment.biz.RecommendBizService;
import com.teemo.equipment.converter.RecommendMapStruct;
import com.teemo.equipment.domain.dto.EquipmentDTO;
import com.teemo.equipment.domain.dto.RecommendAddDTO;
import com.teemo.equipment.domain.dto.RecommendPageDTO;
import com.teemo.equipment.domain.entity.Equipment;
import com.teemo.equipment.domain.entity.EquipmentRecommend;
import com.teemo.equipment.domain.entity.Hero;
import com.teemo.equipment.domain.entity.RecommendRecord;
import com.teemo.equipment.domain.vo.BasePageVO;
import com.teemo.equipment.domain.vo.RecommendVO;
import com.teemo.equipment.enums.StageEnum;
import com.teemo.equipment.service.EquipmentRecommendService;
import com.teemo.equipment.service.EquipmentService;
import com.teemo.equipment.service.HeroService;
import com.teemo.equipment.service.RecommendRecordService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author Teemo
 */
@Service
public class RecommendBizServiceImpl implements RecommendBizService {
    @Resource
    private RecommendRecordService recordService;

    @Resource
    private EquipmentRecommendService recommendService;

    @Resource
    private HeroService heroService;

    @Resource
    private EquipmentService equipmentService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(RecommendAddDTO dto) {
        RecommendRecord record = new RecommendRecord();
        record.setHeroId(dto.getHeroId());
        recordService.save(record);
        List<EquipmentDTO> equipmentList = dto.getEquipmentList();
        List<EquipmentRecommend> recommends = RecommendMapStruct.INSTANCE.toEquipmentRecommendList(equipmentList, record.getId());
        return recommendService.saveBatch(recommends);
    }

    @Override
    public BasePageVO<RecommendVO> page(RecommendPageDTO dto) {
        Page<RecommendRecord> page = recordService.page(dto.pageParam());
        if (CollectionUtil.isEmpty(page.getRecords())) {
            return BasePageVO.convert(page, null);
        }
        // 根据记录获取所有的英雄id
        Set<Long> heroIds = page.getRecords().stream().map(RecommendRecord::getHeroId).collect(Collectors.toSet());
        // 获取英雄信息
        List<Hero> heros = heroService.listByIds(heroIds);
        // 获取记录id
        List<Long> recordIds = page.getRecords().stream().map(RecommendRecord::getId).collect(Collectors.toList());
        // 根据记录id，获取推荐装备
        List<EquipmentRecommend> equipmentRecords = recommendService.listByRecordIds(recordIds);
        // 获取装备id
        Set<Long> equipmentIds = equipmentRecords.stream().map(EquipmentRecommend::getEquipmentId).collect(Collectors.toSet());
        // 根据装备id获取装备信息
        List<Equipment> equipmentList = equipmentService.listByIds(equipmentIds);

        Map<Long, Equipment> equipmentMap = equipmentList.stream().collect(Collectors.toMap(Equipment::getId, Function.identity()));
        Map<Long, Hero> heroMap = heros.stream().collect(Collectors.toMap(Hero::getId, Function.identity()));
        // 先根据recommendRecordId分组，然后根据stage进行分组
        Map<Long, Map<StageEnum, List<EquipmentRecommend>>> recommendGroup = equipmentRecords.stream().collect(Collectors.groupingBy(EquipmentRecommend::getRecommendRecordId, Collectors.groupingBy(EquipmentRecommend::getStage)));

        return BasePageVO.convert(page, e -> RecommendMapStruct.INSTANCE.getRecommendVO(equipmentMap, heroMap, recommendGroup, e));
    }

}
